home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / KELLIS / KEMD.ZIP / KEMD / ADVANCDX.TRA / MINT.DOC next >
Encoding:
Text File  |  1994-11-16  |  55.2 KB  |  1,387 lines

  1. MiNT is Now TOS: A Multitasking OS Extension for the Atari ST/TT/Falcon
  2.  
  3. The MiNT kernel is derived from MiNT, Copyright 1990,1991,1992 Eric R.
  4. Smith. All rights reserved. Used and modified by Atari under license from
  5. Eric Smith; new code and features Copyright 1992,1993,1994 Atari Corporation.
  6.  
  7.  
  8. Introduction
  9.  
  10.  
  11. MiNT is a replacement for (most of) GEMDOS. It is designed to provide
  12. the same kind of services as GEMDOS (file and process management,
  13. primarily) but with extensions to permit such things as multitasking,
  14. interprocess communication, job control, and a flexible file system
  15. interface that permits loadable file systems and device drivers.
  16.  
  17. This document does not discuss the new, multitasking Desktop or utility
  18. programs such as MINIWIN or TCSH. Refer to other documents for
  19. descriptions of these programs.
  20.  
  21. MiNT exists to make your job as a developer easier. You can use MiNT
  22. system calls to do things like run background processes, to set up
  23. interprocess communication, to examine files on disk, or in more
  24. advanced applications to install new kinds of device drivers or
  25. file systems. Your programs generally don't need to know about
  26. MiNT unless they want to take advantage of new MiNT features;
  27. the old GEMDOS calls are still supported for backwards compatibility.
  28.  
  29. Our discussion of MiNT will begin with some of the changes visible
  30. to all users, and then continue with tips about programming MiNT.
  31.  
  32.  
  33. Pseudo Drives
  34.  
  35.  
  36. MiNT provides a fake "disk drive" called U: (for "unified"). There are
  37. "directories" in the root of this drive which contain "files" special to
  38. MiNT. These "files" are not real files, but may represent other objects
  39. such as devices or executing programs. Ordinary file-access calls are used
  40. to deal with them; for instance, writing to U:\DEV\CON is like writing to
  41. the console (as distinct from stdout).
  42.  
  43. The following directories are available on U:
  44.  
  45. U:\DEV
  46.  
  47. Contains files which correspond to the BIOS devices; this allows
  48. you to access these devices from within programs. For example, saving an
  49. ASCII text file to "U:\DEV\PRN" should cause it to be printed on your
  50. printer.
  51.  
  52. The following devices are available by default in U:\DEV (additional device
  53. drivers may be installed by applications):
  54.  
  55.     CENTR   the Centronics (parallel) printer port
  56.     MODEM1  the RS232 serial port
  57.     MIDI    midi port
  58.     KBD     intelligent keyboard controller
  59.     PRN     printer device (usually the parallel port)
  60.     AUX     auxiliary terminal (usually the rs232 port)
  61.     CON     current control terminal
  62.     TTY     same as CON
  63.     STDIN   current file handle 0 (standard input)
  64.     STDOUT  current file handle 1 (standard output)
  65.     STDERR  current file handle 2 (standard error)
  66.     CONSOLE the keyboard/screen
  67.     MOUSE   the mouse (reserved for the operating system)
  68.     NULL    a null device (like Unix's /dev/null)
  69.  
  70. The "STD*" file handles are useful for providing I/O redirection to programs
  71. that normally require file names on the command line, so you
  72. can run such a program in a pipeline.
  73.  
  74.  
  75. U:\PIPE
  76.  
  77. Contains files which are FIFO queues (e.g. pipes). All files
  78. created in U:\PIPE are temporary; when the last program using a FIFO
  79. closes it, it is erased. Normally, U:\PIPE will be empty, but it will
  80. have items on it when you're running a window manager, print spooler,
  81. or similar program that uses FIFOs or pseudo-ttys for communication.
  82. (See the section on FIFOs later in this guide.)
  83.  
  84. U:\PROC
  85.  
  86. Contains special files that represent all currently executing processes,
  87. and their states (such as whether they're running, ready, or waiting, their
  88. process ID numbers, and the amount of memory they've taken.) The "files"
  89. will have names like "GEM.001"; this means that the process name is "GEM"
  90. (usually because it was started from a file like "GEM.SYS"), and its
  91. process ID is 1. You can rename processes just as if they were files,
  92. except that any extension you give is always replaced with the process ID
  93. (e.g. if you rename GEM.001 to FOO.BAR, it will really become
  94. FOO.001). 
  95.  
  96. The "size" of a process file is the amount of memory that is allocated to
  97. it. Note that this is the sum of all memory that the process may
  98. access. The entire size of a shared memory block will be added to every
  99. process which has access to the block. The date and time stamp of a
  100. process file is the data and time that the process was started. A process'
  101. current state is reflected by the attribute bits of the file; most of these
  102. are not visible from the Desktop, but can be checked by programs such
  103. as PS or TOP.
  104.  
  105. Here are the attribute byte combinations for process files on U:\PROC,
  106. and their meanings:
  107.  
  108.     ATTRIBUTE    PROCESS STATE
  109.  
  110.       0x00       currently running
  111.       0x01       ready to run
  112.       0x20       waiting for an event
  113.       0x21       waiting for I/O
  114.       0x22       zombie (exited)
  115.       0x02       terminated and resident (TSR)
  116.       0x24       stopped by a signal
  117.  
  118. The "zombie" state is for processes which have exited, but whose parents
  119. haven't yet learned their exit codes.
  120.  
  121. Deleting a "file" in U:\PROC will send a SIGTERM signal to the
  122. corresponding process, which will usually result in that process being
  123. terminated. It is not possible to delete TSR or zombie processes.
  124.  
  125.  
  126. U:\SHM
  127.  
  128. U:\SHM is a place for shared memory. Processes may create files
  129. in this directory which represent blocks of memory that they wish
  130. to share with other processes. This provides a very fast method
  131. of interprocess communication. (See the section on Shared Memory
  132. later in this guide.)
  133.  
  134.  
  135. Other directories on drive U: are actually other drives. U:\C is
  136. drive C:, so the file C:\MINT\MW.PRG, for instance, is also visible
  137. as U:\C\MINT\MW.PRG.
  138.  
  139.  
  140.  
  141. Background Processes
  142.  
  143.  
  144. Programs may be started in the background. The easiest way to do this
  145. is with the MultiTOS desktop. It can also be done with CLIs such as
  146. TCSH or a similar shell. In TCSH you can say something like:
  147.  
  148.     % cd \foo\src
  149.     % make >& errors &
  150.  
  151. This runs "make" and redirects both its standard output and its error output
  152. to a file called errors. The final "&" means "in the background." The shell
  153. starts the program, then comes back for another command without waiting
  154. for the program to finish running.
  155.  
  156. A background process that tries to write to the console will stop, which
  157. is why the example redirects the output of "make." In the shell, the
  158. command "fg" will bring a stopped process to the foreground. In addition,
  159. the command "stty -tostop" (read that as "set tty, no terminal-output stop")
  160. turns off the stop-on-output feature.
  161.  
  162.  
  163. Pipes
  164.  
  165.  
  166. Pipes are special files that are used to communicate between processes. The
  167. data in a pipe is always in memory, so using a pipe instead of a temporary
  168. file is usually faster; it also doesn't consume disk space. Only a limited
  169. amount of data can be held in a pipe at once; when a process tries to write
  170. more data, it is suspended until another process empties the pipe by reading
  171. some data. If there are no more readers, a process writing on a pipe is
  172. terminated. Writes of 1K or less to a pipe are atomic, that is, if you
  173. make an Fwrite call with 1024 or fewer bytes, these bytes are guaranteed
  174. to be written together; if you try to write more than 1024 bytes to a
  175. pipe, it's possible that your data will be interleaved with the data
  176. of some other process writing to the same pipe, or for a process reading from
  177. the pipe to get your data in chunks, rather than all at once.
  178.  
  179. Again, with TCSH it is easy to demonstrate the use of pipes:
  180.  
  181.     % ls -lt | head
  182.  
  183. This is a "pipeline." The first stage of the pipeline is the program "ls"
  184. which has "-lt" as its argument. That is, "list directory, long form,
  185. sorted by date (most recent first)." The output of "ls" is passed as input
  186. to the next stage of the pipeline, "head." This program displays only the
  187. first 10 lines of its input. The resulting output from this pipeline,
  188. then, is a listing of the 10 most-recent files in the current directory.
  189.  
  190.  
  191. Job Control
  192.  
  193.  
  194. MiNT supports job control. The ^Z (control-Z) key can be used to
  195. suspend a process. The process can be restarted again if it is sent the
  196. appropriate signal. TCSH sends this signal when you use the "fg"
  197. command. TCSH's "bg" command restarts stopped processes, too, but does
  198. so in the background, so they'll stop again if they attempt input or
  199. output. There is also a "delayed" suspend key, ^Y, that takes effect only
  200. when a process attempts to read it.
  201.  
  202. Some programs written for TOS put the terminal in "raw" mode, where no
  203. control characters are interpreted. You can use CTRL-ALT-Z to achieve the
  204. effect of ^Z for such programs. However, this feature should be used with
  205. caution -- it's possible that the TOS program had a good reason for not
  206. wanting to be interrupted.
  207.  
  208. More sophisticated job control facilities can be provided by shells that are
  209. specifically written with MiNT in mind. TCSH demonstrates this. Jobs
  210. run in the background from such shells are automatically stopped when
  211. they attempt to read from the terminal or write to it. Thus, you can run a
  212. long compile in the background, and if an error occurs and the compiler
  213. attempts to write on the screen, it will be stopped.
  214.  
  215. Some other special keys that MiNT interprets are:
  216.  
  217. CTRL-ALT-DEL
  218. Provides a (warm) boot, as in TOS >= 1.4; with the right shift key, you
  219. get a cold boot.
  220.  
  221. Some other keys are recognized by MiNT if the process is doing I/O in
  222. "cooked" mode:
  223.  
  224. ^C (CTRL-C)
  225. Interrupt the running program with signal SIGINT. This (usually)
  226. will kill the process, unless it has made arrangements to catch it.
  227. Note that ^C takes effect immediately under MiNT, whereas under TOS
  228. it only takes effect when the process reads or writes.
  229.  
  230. ^\ (quit)
  231. Send a QUIT signal to a process; usually the same end result as ^C, but
  232. it is guaranteed to kill a TOS program (only MiNT-specific programs
  233. know how to catch it). Use with caution.
  234.  
  235. These keys do \not\ have any effect on processes operating in "raw" mode,
  236. such as editors. However, you can force these to work even on such programs
  237. by holding down the ALT key as well, e.g. CTRL-ALT-C will always send SIGINT
  238. to the process. You should use caution when doing this, since some programs
  239. will function incorrectly and/or lose data if interrupted when they
  240. aren't expecting it.
  241.  
  242.  
  243. Testing for the Presence of MiNT
  244.  
  245.  
  246. The best way to check to see if MiNT is active is to check the cookie jar.
  247. MiNT installs a cookie of 0x4d694e54 (in ASCII, 'MiNT'), with a value
  248. consisting of the major/ minor version numbers in the high/low bytes of the
  249. low word. Thus, MiNT version 1.02 has a cookie value of 0x00000102L.
  250. (This isn't the place to explain the cookie jar, but basically it's a list
  251. of (cookie, value) pairs of longwords, terminated by cookie 0; a pointer to
  252. the jar is found at 0x5a0. MiNT always installs a cookie jar; versions of
  253. TOS prior to 1.6 don't always, in which case 0x5a0 will contain 0).
  254.  
  255.  
  256. File Handles and Devices
  257.  
  258.  
  259. File handle -1 refers to the current control terminal, \not\ necessarily
  260. the console (though this is where it points by default). BIOS handle 2 also
  261. refers to the control terminal, so that e.g. Bconout(2, c) outputs
  262. a character to the control terminal. Thus,
  263.  
  264.     Fforce(-1, Fopen("U:\\DEV\\MODEM1", 2));
  265.     r = Bconin(2);
  266.  
  267. reads a character from the RS232 port under MiNT. This is done so that
  268. programs that use the BIOS for I/O will be able to run in windows or
  269. over the modem. Similarly, the GEMDOS device CON: refers to the current
  270. control terminal, so Fopen("CON:", 2) is normally equivalent to Fdup(-1).
  271. To access the physical console, use device U:\DEV\CONSOLE (but do
  272. this only if you really, really need the output to go to the physical
  273. console; in almost all cases the output should be sent to the control
  274. terminal, since that's where the user will be expecting it to go).
  275.  
  276. In a similar fashion, file handle -2 and bios device 1 (GEMDOS device AUX:)
  277. may be redirected away from the RS232 port (device U:\DEV\MODEM1), and
  278. file handle -3 and bios device 0 (GEMDOS device PRN:) may be directed away
  279. from the Centronics printer port (device U:\DEV\CENTR). Since both the
  280. GEMDOS handles and BIOS device numbers are redirected, any program at all
  281. will obey the redirection unless it accesses the hardware directly (or
  282. unless it was written for MiNT and specifically uses the new device names
  283. like U:\DEV\CENTR; this should be done only if \absolutely\ necessary!)
  284. See also the PRN= and CON= commands for mint.cnf, which provide another
  285. way to redirect the printer and console. (Actually, they're just another
  286. interface to the same method of redirection.)
  287.  
  288. File handles -4 and -5 are new with MiNT, and refer to the MIDI input
  289. and output devices respectively. Redirecting these handles will affect
  290. BIOS operations on bios device 4 (the MIDI port). This is so
  291. programs that do MIDI I/O using BIOS device 4 can be connected in a special
  292. kind of pipeline.
  293.  
  294.  
  295. Programming with MiNT
  296.  
  297. A file (MINTBIND.H) is provided that gives a C interface to the new
  298. MiNT system calls. Users of other programming languages will have to write
  299. the interfaces themselves. This should be relatively straightforward, so
  300. long as your compiler provides a way to call GEMDOS directly.
  301.  
  302.  
  303. Interprocess Communication
  304.  
  305.  
  306. MiNT provides many forms of interprocess communication (IPC): signals, fifos,
  307. shared memory, message passing, and semaphores.
  308.  
  309. Signals
  310.  
  311.  
  312. MiNT introduces the new (to TOS) concept of a signal. If you're
  313. familiar with Unix/Posix signals, then MiNT signals will will be
  314. easy to learn; but note that there are some (not so subtle) differences
  315. between MiNT and Unix!
  316.  
  317. A signal is a small non-negative integer that represents an exceptional event;
  318. usually something that is very urgent. It's somewhat like an interrupt or
  319. exception to the CPU, only it's implemented in the operating system
  320. instead of in the hardware. Like many exceptions (bus errors, etc.) signals
  321. are usually fatal. Most signals can be caught by programs (so that a
  322. program-defined routine is called) or ignored; if a signal is caught or
  323. ignored, it is no longer fatal. Signals can also be blocked; a
  324. blocked signal is not acted upon until it is unblocked.
  325.  
  326. A signal is said to be sent to a process when the exceptional
  327. condition related to that signal occurs, or when another process sends
  328. the signal with the Pkill() system call. The signal is said to
  329. be delivered to the process when that process wakes up and
  330. begins to take whatever actions are appropriate for the signal. Note
  331. that there may be a considerable time interval between the sending of
  332. a signal and its delivery. For example, if process A has blocked the
  333. SIGHUP signal (signal 1), then no SIGHUP will be delivered to it until
  334. it has unblocked that signal, even if process B sends it SIGHUP with
  335. the Pkill() system call. Note also that a signal is not
  336. necessarily delivered the same number of times that it is sent. If both
  337. process B and process C send SIGHUP to process A, when process A
  338. unblocks SIGHUP only one SIGHUP will be delivered. This is because signals
  339. are like flags; once a flag has been set (the signal is sent) setting
  340. the flag again will have no effect until it has been cleared (the signal
  341. is delivered).
  342.  
  343. What Signals Are There?
  344.  
  345. There are 32 possible signals, 0-31. Not all of these have been assigned
  346. a meaning under MiNT. Here are the ones that have been given a meaning;
  347. we give the symbolic name for the signal, the corresponding integer,
  348. and the "traditional" meaning for the process that the signal is sent to.
  349. Any signal not listed here should be considered as "reserved" and should not
  350. be used by applications.
  351.  
  352. Unless otherwise noted, the default action for signals is to terminate
  353. the process.
  354.  
  355. #define    SIGNULL        0    /* No default action */
  356. This isn't really a signal at all; it is never delivered to processes
  357. and has no effect. It exists only so that processes can test to see if
  358. a particular child process has exited, by attempting to send SIGNULL
  359. to the child. If the child exists, the attempt will succeed but nothing
  360. will be done. If the child has terminated, the caller will get an error.
  361. It is not possible to catch or block this signal, since it is never
  362. sent to processes anyway.
  363.  
  364. #define SIGHUP        1
  365. "The terminal that you're connected to is no longer valid." This signal
  366. is commonly sent by, for example, window managers when the user has
  367. closed the window. Processes should not attempt any I/O to their
  368. controlling terminal after receiving this signal, and indeed should probably
  369. exit unless the user has specifically asked them to continue.
  370.  
  371. #define SIGINT        2
  372. "Please stop what you're doing." This signal is sent when the user presses
  373. control-C. It usually means that the user wishes the process to stop its
  374. current task. Non-interactive processes should generally exit when they
  375. receive this signal; interactive processes may wish to catch SIGINT
  376. so that the user can use it to break out of time-consuming tasks and
  377. return to a command prompt.
  378.  
  379. #define SIGQUIT        3
  380. "Stop what you're doing, something's gone wrong!" This signal is sent when
  381. the user presses control-\. It usually indicates a desire to immediately
  382. abort the process because of an error that the user has noticed. It is
  383. generally thought to be "stronger" than SIGINT, and exiting (perhaps after
  384. cleaning up data structures) is an appropriate response to this.
  385.  
  386. #define SIGILL        4
  387. "An illegal instruction has been encountered." This corresponds to the
  388. 680x0 illegal instruction trap, and usually indicates a very serious error;
  389. catching this signal is generally unwise.
  390.  
  391. #define SIGTRAP        5
  392. "The single-step trace trap has been encountered." This corresponds to the
  393. 680x0 trace trap, and is usually activated (and handled) by debuggers;
  394. user programs shouldn't catch this.
  395.  
  396. #define SIGABRT        6
  397. "An awful error has occured." This is commonly sent by the abort library
  398. function, and indicates that something has gone very, very wrong (for
  399. example, data structures have been unexpectedly corrupted). It is unlikely
  400. that anything useful can be done after this signal is sent; programs
  401. should not normally catch or ignore SIGABRT.
  402.  
  403. #define SIGPRIV        7
  404. "Privilege violation." An attempt has been made to execute an instruction
  405. in user mode that is normally restricted to supervisor mode; this corresponds
  406. to the 680x0 privilege violation exception, and indicates a serious error.
  407.  
  408. #define SIGFPE        8
  409. "Division by zero or a floating point error has occured." Processes may
  410. ignore or catch this signal (which corresponds to the 680x0 division by zero
  411. trap) and deal with it as they see fit.
  412.  
  413. #define SIGKILL        9    /* Cannot be blocked or caught */
  414. "Die!" This signal will never be seen by a process; nor can processes
  415. block it. Sending SIGKILL is a way to be sure of killing a run-away
  416. process. Use it only as a last resort, since it gives the process no
  417. chance to clean up and exit gracefully.
  418.  
  419. #define SIGBUS        10
  420. "Bus error." Corresponds to the 680x0 bus error exception, and indicates
  421. a very serious error; programs should generally not attempt to ignore
  422. or catch this signal.
  423.  
  424. #define SIGSEGV        11
  425. "Illegal memory reference." Corresponds to the 680x0 address error
  426. exception, and indicates a very serious error; catching or ignoring this
  427. signal is not recommended.
  428.  
  429. #define SIGSYS        12
  430. "Bad argument to a system call." This signal is sent when an illegal
  431. (usually, out of range) parameter is sent to a system call, and when that
  432. system call does not have any "nice" way to report errors. For example,
  433. Super(0L) when the system is already in supervisor mode causes SIGSYS to
  434. be raised. Note that the kernel does not always detect illegal/out of
  435. range arguments to system calls, only sometimes.
  436.  
  437. #define SIGPIPE        13
  438. "A pipe you were writing to has no readers." Programs may catch this signal
  439. and attempt to exit gracefully after receiving it; note that exiting is
  440. appropriate because the standard output is probably no longer connected
  441. to anything.
  442.  
  443. #define SIGALRM        14
  444. "The alarm you set earlier has happened." This signal is sent to processes
  445. when the alarm clock set by Talarm (q.v.) expires. It's very
  446. common to catch this signal and from the signal handler jump to a known
  447. point in the program; for example, to indicate a timeout while attempting
  448. to communicate over a serial line.
  449.  
  450. #define SIGTERM        15
  451. "Please die." This is a polite form of SIGKILL (#9). Programs should
  452. respect this nice request; they may want to catch the signal to perform
  453. some cleanup actions, but they should then exit (since if they don't,
  454. the user will probably get mad and send SIGKILL later anyway...). This
  455. is the signal that is sent when a process is dragged to the trashcan on
  456. the desktop.
  457.  
  458. #define SIGSTOP        17    /* Default action: suspend the process */
  459. "Suspend yourself." This signal is sent to a process when it should be
  460. stopped temporarily. SIGSTOP is used primarily by debuggers and similar
  461. programs; suspensions requested directly by the user usually are signalled
  462. by SIGTSTP (q.v.) This signal cannot be ignored, blocked, or caught.
  463.  
  464. #define SIGTSTP        18    /* Default action: suspend the process */
  465. "The user is asking you to suspend yourself." This signal is sent immediately
  466. when the user presses the control-Z key, and is sent when the process tries
  467. to read a control-Y key in cooked mode (for a delayed stop). In both cases,
  468. the process should suspend itself. Since this is the default action, no
  469. special handling is normally required, although some programs may wish to
  470. save the screen state and restore it when they are unsuspended.
  471.  
  472. #define SIGCONT        19    /* Default action: continue a stopped
  473.                      process */
  474. "You are being restarted after having been suspended." This signal is
  475. sent by shells to resume a suspended process. If the process is not
  476. suspended, the signal does nothing. This signal cannot be blocked, but
  477. it *is* possible to install a handler for it (this is rarely necessary,
  478. though).
  479.  
  480. #define SIGCHLD        20    /* Default action: no action taken */
  481. "One of your children has been suspended or has exited." This signal is
  482. sent by the kernel to the parent of any process that is terminated (either
  483. because of a signal or by a Pterm, Pterm0, or Ptermres system call) or
  484. which is suspended because of a signal. Programs that are concerned with the
  485. status of their children (for example, shells) may wish to catch this signal;
  486. after a SIGCHLD has been received, the Pwait3 system call may be
  487. used to determine exactly which child has exited or been suspended.
  488. Note that the Psigaction system call may be used to force SIGCHLD to be
  489. delivered only when a child process terminates (so that suspension of
  490. child processes, for example via job control, does not raise SIGCHLD.
  491.  
  492. #define SIGTTIN        21    /* Default action: suspended the process */
  493. "Attempt to read from a terminal you don't own." This signal is sent to
  494. any process that attempts to do input from a terminal with a different
  495. process group than their own. Usually, this happens if the user has started
  496. the job in the background; the process will be suspended until the user
  497. explicitly brings it to the foreground with the appropriate shell command
  498. (at which time the shell will reset the terminal's process group and
  499. send the stopped process a SIGCONT signal to tell it to continue).
  500. [NOTE: in fact, SIGTTIN and SIGTTOU are sent to all processes in the same
  501. process group as the process that attempted to do the i/o; this is for
  502. compatibility with Unix, and it simplifies the implementation of job
  503. control shells.]
  504.  
  505. #define SIGTTOU        22    /* Default action: suspend the process */
  506. "Attempt to write to a terminal that you don't own." Similar to SIGTTIN (q.v.).
  507. Processes should normally respect the user's job control and should
  508. override or ignore SIGTTOU only in situations where a very critical error
  509. has occured and a message must be printed immediately.
  510.  
  511. #define SIGXCPU        24
  512. "Your CPU time limit has been exhausted." Sent to processes when they have
  513. consumed more than the maximum number of milliseconds of CPU time allowed
  514. by the Psetlimit() system call. The signal will continue to be sent to
  515. the process until it exits; if a process does catch this signal, it should
  516. do whatever clean up actions are necessary and then terminate.
  517.  
  518. #define SIGWINCH    28    /* Default action: no action taken */
  519. "The window you were running in has changed size." This signal is sent
  520. to processes by some window managers to indicate that the user has changed
  521. the size of the window the process is running in. If the process cares
  522. about the window size, it may catch this signal and use an Fcntl call
  523. to inquire about the new window size when the signal is received.
  524. (See the documentation for Fcntl for details.)
  525.  
  526. #define SIGUSR1        29
  527. #define SIGUSR2        30
  528.  
  529. These two signals are reserved for applications, which may define whatever
  530. meaning they wish for them. Note, however, that these signals do
  531. terminate processes by default, so don't send them to a process which
  532. isn't prepared to deal with them.
  533.  
  534.  
  535. System Calls Dealing With Signals
  536.  
  537.  
  538. WORD
  539. Pkill( WORD pid, WORD sig )
  540.  
  541. If pid > 0, then the given signal (see the numbers above) is sent to the
  542. process with that pid.
  543. If pid == 0, then the given signal is sent to all members of the process
  544. group of the process making the Pkill call. This includes, of course,
  545. the process itself.
  546. If pid < 0, the signal is sent to all members of process group (-pid).
  547.  
  548. Returns:
  549. 0     for successful sending of the signal
  550.     (Note that if the current process is a recipient of the signal,
  551.     and the signal proves to be fatal, then Pkill will never return.)
  552. ERANGE    if "sig" is less than 0 or greater than 31
  553. EFILNF    if pid > 0 and the indicated process has terminated or does not
  554.     exist, or if pid < 0 and there are no processes in the given
  555.     process group
  556. EACCDN  if the sending process is not authorized to send signals to
  557.     the specified receiving process or group (for example, they
  558.     belong to different users)
  559.  
  560.  
  561. #define SIG_DFL (0L)
  562. #define SIG_IGN (1L)
  563.  
  564. LONG
  565. Psignal( WORD sig, LONG handler )
  566.  
  567. Change the handling of the indicated signal.
  568.  
  569. If "handler" is SIG_DFL, then the default action for the signal will occur when
  570. the signal is delivered to the current process.
  571.  
  572. If "handler" is SIG_IGN, then the signal will be ignored by the process, and
  573. delivery of the signal will have no noticeable effect (in particular, the
  574. signal will not interrupt the Pause system call, q.v.). If the signal
  575. is pending at the time of the Psignal call, it is discarded.
  576.  
  577. If "handler" is any other value, it is assumed to be the address of a
  578. user function that will be called when the signal is delivered to the
  579. process. The user function is called with a single LONG argument on
  580. the stack, which is the number of the signal being delivered (this is done
  581. so that processes may use the same handler for a number of different
  582. signals). While the signal is being handled, it is blocked from delivery;
  583. thus, signal handling is "reliable" (unlike Version 7 and early System V
  584. Unix implementations, in which delivery of a second signal while it
  585. was being handled could kill the process). Also note that, unlike some
  586. versions of Unix, the signal handling is *not* reset to the default action
  587. before the handler is called; it remains set to the given signal handler.
  588.  
  589. The signal handler must either return (via a normal 680x0 rts instruction)
  590. or call the Psigreturn system call to indicate when signal handling is
  591. complete; in both cases, the signal will be unblocked. Psigreturn also
  592. performs some internal clean-up of the kernel stack that is necessary if
  593. the signal handler is not planning to return (for example, if the C
  594. longjmp() function is to be used to continue execution at another point
  595. in the program).
  596.  
  597. Signal handlers may make any GEMDOS, BIOS, or XBIOS system calls freely.
  598. GEM AES and VDI calls should not be made in a signal handler.
  599.  
  600. Note that calling Psignal to change behavior of a signal has the side
  601. effect of unmasking that signal, so that delivery is possible. This is done
  602. so that processes may, while handling a signal, reset the behavior and
  603. send themselves another instance of the signal, for example in order
  604. to suspend themselves while handling a job control signal.
  605.  
  606. Signal handling is preserved across Pfork and Pvfork calls. Signals
  607. that are ignored by the parent are also ignored by the child after a Pexec
  608. call; signals that were being caught for handling in a function are reset
  609. in the child to the default behavior.
  610.  
  611. Returns:
  612. The old value of handler on success.
  613. ERANGE    if sig < 1 or sig > 31
  614. EACCDN    if sig cannot be caught by the user (i.e. SIGKILL or SIGSTOP)
  615.  
  616. Bugs:
  617. Signal handling can be nested only a small (around 3) number of times,
  618. i.e. if 4 signals are delivered to a process, and the process has established
  619. handlers for all 4, and none of the handlers has returned or called
  620. Psigreturn, then there is a very good chance of a stack overflow killing
  621. the process off. In practice, this is unlikely to happen.
  622.  
  623.  
  624. LONG
  625. Psigblock( LONG amask )
  626.  
  627. Block receipt of some signals. The "amask" argument is added to the
  628. current set of signals being masked, i.e. the new set of blocked signals
  629. is the union of the old set and the set represented by amask. Sets of
  630. blocked signals are represented by a 32 bit unsigned long quantity, with
  631. bit (1L << sig) set if signal "sig" is to be blocked, and clear if not.
  632.  
  633. Blocked signals remain blocked across Pfork and Pvfork calls. For Pexec
  634. calls, children always start out with an empty set of blocked signals,
  635. regardless of which signals are blocked in the parent.
  636.  
  637. Returns:
  638. The old set of blocked signals (i.e. the set as it was before amask
  639. was added to it).
  640.  
  641. NOTE: Certain signals (SIGKILL, SIGSTOP, SIGCONT) cannot be blocked;
  642. if the corresponding bits are set in amask, the kernel will clear them
  643. but will not report an error.
  644.  
  645.  
  646. LONG
  647. Psigsetmask( LONG mask )
  648.  
  649. Decide which signals are to be blocked from delivery. Unlike Psigblock
  650. (which adds to the set of blocked signals) Psigsetmask changes the
  651. entire set, replacing the old set of blocked signals with the one
  652. specified in "mask". As with Psigblock, signal n is blocked from
  653. delivery if bit (1L << n) is set in mask. Note that certain signals
  654. cannot be blocked, and if the corresponding bits are set in the
  655. mask the kernel will clear them.
  656.  
  657. Returns:
  658. The old set of blocked signals.
  659.  
  660. Usage:
  661. Typically, Psigblock and Psigsetmask are used together to temporarily
  662. block signals, e.g.:
  663.  
  664.     oldmask = Psigblock( (1L << SIGINT) );
  665.     ... do some things with SIGINT blocked from delivery ...
  666.     (void) Psigsetmask(oldmask);
  667.  
  668.  
  669.  
  670. LONG
  671. Psigpending()
  672.  
  673. Give an indication of what signals are pending (i.e. have been sent to
  674. the process but not yet delivered, probably because they are blocked
  675. from delivery).
  676.  
  677. Returns:
  678. A 32 bit unsigned long representing the set of signals that are pending.
  679. Signal n is pending if bit (1L << n) is set in the returned value.
  680.  
  681.  
  682. void
  683. Psigreturn()
  684.  
  685. Terminate signal handling. This call should be used by any signal
  686. handler that is not planning to return to the kernel (i.e. if the
  687. handler is going to execute a non-local jump to another point in the
  688. program). It cleans up the signal delivery stack and unblocks the
  689. signal that was being delivered. Calling Psigreturn when no signal
  690. is being delivered is harmless.
  691.  
  692. Bugs:
  693. Calling Psigreturn from a signal handler, and then actually returning
  694. from that handler, is likely to produce extremely unpleasant results.
  695. Don't do it.
  696.  
  697.  
  698. void
  699. Pause()
  700.  
  701. Wait until a signal is delivered. This call will return after any (non-fatal)
  702. signal has been delivered to the process. Note that signals that are being
  703. ignored are never delivered.
  704.  
  705.  
  706. void
  707. Psigpause( LONG mask )
  708.  
  709. Block the set of signals specified by "mask", and then wait until
  710. a signal is delivered. This call will return after any (non-fatal)
  711. signal has been delivered to the process. Before returning, the signal
  712. mask is restored to its original value.
  713.  
  714.  
  715.  
  716. struct sigaction {
  717.     LONG    sa_handler;
  718.     LONG    sa_mask;
  719.     WORD    sa_flags;
  720. #define SA_NOCLDSTOP 1;
  721. }
  722.  
  723. WORD
  724. Psigaction( WORD sig, struct sigaction *act, struct sigaction *act )
  725.  
  726. Like Psignal, this call changes the handling of the indicated signal.
  727. If "act" is non-zero, it is a pointer to a structure which describes
  728. the new signal handling behavior, as follows:
  729.  
  730. sa_handler    is the function to be called when the signal is delivered,
  731.         or SIG_DFL, or SIG_IGN. For further information about
  732.         signal handling functions, see Psignal.
  733. sa_mask        is a set of additional signals to mask while the signal
  734.         is being delivered. The signal itself is always masked,
  735.         but sometimes it might be desireable to mask some
  736.         other signals as well; this allows a "prioritization"
  737.         of signals
  738. sa_flags    extra flags which can affect the behavior of the
  739.         signal. This field should normally be set to 0.
  740.         If "sig" is SIGCHLD and "flags" is SA_NOCLDSTOP,
  741.         then the SIGCHLD signal will not be delivered to
  742.         this process when one of its children are stopped.
  743.  
  744. If "oact" is non-zero, then the old signal handling behavior is
  745. copied into "oact" and returned.
  746.  
  747. Returns:
  748. 0 on success
  749. ERANGE    if sig < 1 or sig > 31
  750. EACCDN    if sig cannot be caught by the user
  751.  
  752. Usage:
  753. If "sig" is a valid signal, the call:
  754.     foo = Psignal(sig, newfunc)
  755. is equivalent to:
  756.     struct sigaction newact, oact;
  757.     newact->sa_mask=0L;
  758.     newact->sa_flags=0;
  759.     newact->sa_handler = newfunc;
  760.     Psigaction(sig, &newact, &oact);
  761.     foo = oact->sa_handler;
  762.  
  763.  
  764. LONG
  765. Talarm( LONG s )
  766.  
  767. If s > 0, schedule a SIGALRM signal to occur in s seconds. This alarm
  768. will replace any previously scheduled alarm.
  769. If s = 0, cancel any previously scheduled alarm.
  770. If s < 0, inquire about a scheduled alarm but do not change it.
  771.  
  772. Returns:
  773. If an alarm was previously scheduled, returns the number of seconds remaining
  774. until that previously scheduled alarm. Otherwise, returns 0.
  775.  
  776. Bugs:
  777. Internal calculations are done in milliseconds, not seconds, so the returned
  778. value is not exactly accurate.
  779. For the same reason, setting an alarm more than 2 million seconds or so
  780. into the future will not work correctly.
  781.  
  782.  
  783. FIFOs
  784.  
  785.  
  786. FIFOs are "first in first out" message queues. Pipes are a special kind of
  787. (unidirectional) FIFO. FIFOs are represented by files in the subdirectory
  788. "PIPE" on drive "U:." They are created with the Fcreate(name, flags)
  789. system call. "name" will be the name under which the fifo is known
  790. (maximum 13 characters); "flags" is explained below. The returned file handle
  791. is treated just like an ordinary file, and may be written to and read from
  792. (unless the fifo is unidirectional, in which case it may only be written to).
  793. The program that creates the FIFO is normally called the "server." Other
  794. programs ("clients") may use the Fopen(name, mode) system call to open the
  795. other end of the FIFO and read the data that the server writes, or write data
  796. for the server to read. When the last program (either client or server) using
  797. a FIFO closes it, the FIFO is deleted automatically. Note that one program can
  798. be both client and server, if it creates a FIFO with Fcreate and then opens it
  799. again with Fopen. Also, children of the server can inherit the Fcreate'd file
  800. handle and thus have access to the "server" side of the FIFO.
  801.  
  802. The bits in the "flags" argument to Fcreate have the following meanings:
  803.  
  804. 0x01
  805. Make the FIFO unidirectional (server can write, clients can read).
  806.  
  807. 0x02
  808. Cause reads to return EOF if no other processes are writing, and writes
  809. to raise the SIGPIPE signal if no other processes are reading. The
  810. default action (if this flag is not given) is to block waiting for
  811. reads and writes.
  812.  
  813. 0x04
  814. Make the FIFO a pseudo-tty; to client processes, the FIFO will act
  815. just like a terminal with the server "typing" the characters; for
  816. example, if the server writes a control-C, SIGINT will be sent to clients.
  817. Data can be passed through such a FIFO in long words rather than bytes,
  818. if the Fputchar() system call is used.
  819. This allows the server program to pass the extended BIOS information
  820. (such as the shift key status and scan code) to be returned by Bconin()
  821. calls on the client side of the FIFO. The 'extra' 3 bytes of the longword
  822. could also be used for other out of band data.
  823.  
  824. 0x20
  825. Make the FIFO support Unix style "read" semantics; i.e. Fread() will
  826. return as soon as any bytes are available on the FIFO, and will return
  827. the number of bytes read. If this flag is clear, then Fread() will not
  828. return until the number of bytes specified in the Fread() call have been
  829. read, or until there are no more writers on the FIFO.
  830.  
  831. Attempting to Fcreate() a FIFO with the same name as an already existing
  832. one will result in an access error (i.e. the Fcreate() will fail).
  833.  
  834. Pipes may be created through the Fpipe() system call as well as through
  835. the Fcreate()/Fopen() pair; the former method is easier, since the kernel
  836. takes care of name conflicts, etc. Pipes created in this way
  837. will be unidirectional, and will have Unix read semantics.
  838.  
  839. FIFOs may be locked by processes via the Fcntl() system call, as follows:
  840.  
  841. /* values for the l_type field */
  842. #define F_RDLCK 0
  843. #define F_WRLCK 1
  844. #define F_UNLCK 3
  845.  
  846. struct flock {
  847.     short   l_type;     /* type of lock */
  848.     short   l_whence;   /* what is the lock relative to? */
  849.     long    l_start;    /* start of locked region */
  850.     long    l_len;      /* 0 for "rest of file" */
  851.     short   l_pid;      /* set by F_GETLK */
  852. };
  853. .fi
  854.  
  855. The "l_whence" field takes a value like the "whence" argument of Fseek():
  856. zero means "from the beginning," one means "from the current position," and
  857. two means "from the end." The l_start field is added to the appropriate
  858. offset in the file and the lock starts there.
  859.  
  860. Fcntl(fd, &lock, F_SETLK)
  861. Set a lock as specified by the lock structure.
  862. The current version of MiNT only understands locks on the whole FIFO,
  863. so lock.l_start and lock.l_len should both be 0.
  864. If lock.l_type is F_UNLCK,
  865. then the lock is released. Otherwise, the whole file is locked
  866. (future versions of MiNT may distinguish between read and write locks,
  867. but for now all locks are treated as write locks (F_WRLCK) and block both
  868. reads and writes). If another process has locked the fifo, the
  869. Fcntl call returns EACCDN (-36). If a process holding a lock terminates,
  870. the FIFO is automatically unlocked.
  871.  
  872. Fcntl(fd, &lock, F_GETLK)
  873. If a lock exists on the fifo, set lock to
  874. indicate what kind of lock it is; otherwise, set lock.l_type
  875. to F_UNLCK.
  876.  
  877. Locks are only "advisory"; that is, a lock on a file prevents obtaining
  878. another lock, but does not actually prevent reads and writes.
  879. Thus, programs may ignore locks if they
  880. choose to do so. However, if all programs that use a fifo also use locks,
  881. two clients' data will not be not mixed together in that fifo.
  882.  
  883. Using FIFOs:
  884.  
  885. FIFOs are actually very easy to use. Here are some things to keep in mind:
  886.  
  887. (1) The server program (the one that's going to be listening
  888.     for requests from clients) should create the FIFO with
  889.     Fcreate(). The file descriptor returned from Fcreate() is
  890.     the "server" descriptor; descriptors returned by Fopen() will
  891.     be "client" descriptors. Data written to the server descriptor
  892.     can be read by client descriptors, and vice-versa.
  893. (2) FIFOs are by default bidirectional. You can create a single
  894.     directional FIFO by creating the fifo "read only"; in this case,
  895.     only the server descriptor can be written to, and only client
  896.     descriptors can be read from.
  897. (3) Be careful not to mix data up; if two clients are trying to
  898.     read from the same FIFO at the same time, they each may read
  899.     data intended for the other. The easiest way to avoid this is
  900.     by having every client lock the FIFO before accessing it,
  901.     and unlock the FIFO when finished. It's also possible (if you're
  902.     careful) to use the fact that all writes of <1024 bytes are atomic
  903.     (i.e. take place in one "chunk") to avoid interleaving of data;
  904.     but locks are probably safer.
  905.  
  906. Here is a sample pair of applications. The server program ("fortserv.c")
  907. creates a FIFO and listens on it for requests. When it receives a
  908. request, it writes a cute saying (a "fortune cookie") back to the FIFO.
  909. The client program ("fortune.c") opens the FIFO, writes a request,
  910. reads the response, and prints the result on the terminal. These are
  911. very simple minded applications, but it should give you an idea of
  912. the flavour of how to use FIFOs for interprocess communication.
  913. -------------------------- fortserv.c -------------------------
  914. /* fortune server: send cookies to clients */
  915. /* illustrates server side use of fifos */
  916.  
  917. /*
  918.  * This program opens a fifo ("U:\PIPE\FORTUNE")
  919.  * and listens to requests on that fifo. When it
  920.  * gets a request (consisting of a single '?'
  921.  * character) it writes back as a reply a 1 byte
  922.  * "length" followed by a randomly selected saying.
  923.  * BUGS:
  924.  *   - maximum of 255 characters for a fortune
  925.  *   - the fortunes aren't particularly interesting
  926.  */
  927.  
  928. #ifdef __GNUC__
  929. #include <minimal.h>
  930. #endif
  931. #include <osbind.h>
  932. #include <mintbind.h>
  933. #include <string.h>
  934.  
  935. #define FIFONAME "U:\\PIPE\\FORTUNE"
  936. #define MAXSIZE 255
  937.  
  938. /* witty (?) sayings */
  939.  
  940. char * sayings[] = {
  941. "Core fault -- program dumped.",
  942. "Don't worry, be happy!",
  943. "Help! I'm trapped in a fortune cookie factory!",
  944. "\"Home is where you wear-a your hat.\"",
  945. "I want a cookie.",
  946. "MS-DOS: just say \"no\".",
  947. "Never play leapfrog with a unicorn.",
  948. "No matter where you go, there you are.",
  949. "Sorry, I'm out of short, pithy sayings today.\r\nTry again later.",
  950. "They say that playing NetHack is like walking into a death trap.",
  951. "Vision hazy, try again later.",
  952. "What? You expected something funny?",
  953. "Why is it that UFO's always seem to visit idiots?",
  954. "Your puny intellect is no match for our superior weapons.",
  955. };
  956. #define NUMSAYINGS (sizeof(sayings) / sizeof(char *))
  957.  
  958. /* file descriptor for the fortune fifo */
  959. int fd;
  960.  
  961.  
  962. /* send a witty saying out through the fifo */
  963.  
  964. void
  965. send_saying()
  966. {
  967.     int i;
  968.     char *s;
  969.     char tmpbuf[MAXSIZE+1];
  970.  
  971. /* pick a saying at random */
  972.     i = ((unsigned)Random() >> 1) % NUMSAYINGS;
  973.     s = sayings[i];
  974.  
  975. /* construct the message to send */
  976.     i = (int)strlen(s);
  977.     tmpbuf[0] = i;
  978.     strcpy(tmpbuf+1,s);
  979.  
  980. /* we really should check for an error */
  981.     (void)Fwrite(fd, (long)i+1, tmpbuf);
  982. }
  983.  
  984. /* main function: create the fifo, then sit around
  985.  * listening for requests
  986.  */
  987.  
  988. int
  989. main(argc, argv, envp)
  990.     int argc;
  991.     char **argv, **envp;
  992. {
  993.     char c;
  994.     long r;
  995.  
  996.     fd = Fcreate(FIFONAME, 0);
  997.     if (fd < 0) {
  998.         Cconws("Couldn't create ");
  999.         Cconws(FIFONAME);
  1000.         Cconws("!\r\n");
  1001.         Pterm(1);
  1002.     }
  1003.  
  1004.     for(;;) {
  1005.         r = Fread(fd, 1L, &c);
  1006.         if (r != 1) {    /* read error?? */
  1007.             break;
  1008.         }
  1009.         if (c == '?') {    /* request for saying */
  1010.             send_saying();
  1011.         }
  1012.     /* could have other requests here */
  1013.     }
  1014.     return 0;
  1015. }
  1016. ------------------------ fortune.c ----------------------
  1017. /* fortune client: get a fortune cookie from
  1018.  * the fortune server
  1019.  */
  1020.  
  1021. /* illustrates client side use of fifos */
  1022.  
  1023. #ifdef __GNUC__
  1024. #include <minimal.h>
  1025. #endif
  1026. #include <osbind.h>
  1027. #include <mintbind.h>
  1028.  
  1029. #define FIFONAME "U:\\PIPE\\FORTUNE"
  1030. #define BUFSIZ 256
  1031. #define F_SETLKW 7
  1032.  
  1033. struct flock {
  1034.     short l_type;            /* type of lock */
  1035. #define F_RDLCK        0
  1036. #define F_WRLCK        1
  1037. #define F_UNLCK        3
  1038.     short l_whence;            /* SEEK_SET, SEEK_CUR, SEEK_END */
  1039.     long l_start;            /* start of locked region */
  1040.     long l_len;            /* length of locked region */
  1041.     short l_pid;            /* pid of locking process
  1042.                         (F_GETLK only) */
  1043. };
  1044.  
  1045. int
  1046. main(argc, argv, envp)
  1047.     int argc;
  1048.     char **argv, **envp;
  1049. {
  1050.     int fd;
  1051.     char buf[BUFSIZ];
  1052.     unsigned char len;
  1053.     struct flock lock;
  1054.     long r;
  1055.  
  1056. /* open the fifo */
  1057.     fd = Fopen(FIFONAME, 2);
  1058.     if (fd < 0) {
  1059.         Cconws("Couldn't open ");
  1060.         Cconws(FIFONAME);
  1061.         Cconws("!\r\n");
  1062.         Pterm(1);
  1063.     }
  1064.  
  1065. /* get a lock; this makes sure that two fortune
  1066.  * programs don't try to send requests and read
  1067.  * replys at the same time
  1068.  */
  1069.  
  1070.     lock.l_type = F_WRLCK;
  1071.  
  1072. /* lock the whole file -- only thing that makes sense
  1073.  * for a fifo
  1074.  */
  1075.     lock.l_whence = 0;
  1076.     lock.l_start = lock.l_len = 0L;
  1077.  
  1078.     r = Fcntl(fd, &lock, F_SETLKW);
  1079.     if (r != 0) {
  1080.         Cconws("Couldn't get a lock!\r\n");
  1081.         Pterm(r);
  1082.     }
  1083.  
  1084. /* write the request */
  1085.     Fwrite(fd, 1L, "?");
  1086. /* wait for a reply */
  1087. /* the fortune server writes a 1 byte length, followed by
  1088.  * the fortune itself
  1089.  */
  1090.     r = Fread(fd, 1L, &len);
  1091.     if (r != 1L || len != Fread(fd, (long)len, buf)) {
  1092.         Cconws("Error reading fortune!\r\n");
  1093.         Pterm(1);
  1094.     }
  1095.     buf[len] = 0;
  1096.  
  1097. /* unlock the fifo */
  1098.  
  1099.     lock.l_type = F_UNLCK;
  1100.     (void) Fcntl(fd, &lock, F_SETLKW);
  1101.  
  1102.     Fclose(fd);
  1103.  
  1104. /* now write the fortune to the screen */
  1105.     Cconws(buf);
  1106.     Cconws("\r\n");
  1107.  
  1108.     return 0;
  1109. }
  1110.  
  1111.  
  1112. Shared Memory
  1113.  
  1114.  
  1115. Children created with the Pexec(4,...) or with Pexec(104,...) share all of
  1116. their parent's memory, as do children created with the Pvfork() system call.
  1117. Hence, they may communicate with their parent (or with each other) via
  1118. global variables.
  1119.  
  1120. A more general shared memory mechanism is provided by U:\SHM. Files in
  1121. that directory represent blocks of memory. A program may offer to share
  1122. its memory by creating a file in U:\SHM and executing an Fcntl call
  1123. (SHMSETBLK) to associate a block of memory with the file. Other programs
  1124. may then open the file and do a SHMGETBLK call to gain access to that
  1125. memory.
  1126.  
  1127. To create a shared memory file, a program uses the Fcreate() call
  1128. to create a file in U:\SHM, e.g.:
  1129.  
  1130. fd = Fcreate("U:\\SHM\\MY.SHARE", 0);
  1131.  
  1132. It then uses an Fcntl() call to attach a block of memory (previously
  1133. allocated by Malloc() or Mxalloc()) to the file:
  1134.  
  1135. blk = Malloc(128L);
  1136. Fcntl(fd, blk, SHMSETBLK);
  1137.  
  1138.  
  1139. Several things should be noted when creating a shared memory
  1140. file:
  1141.  
  1142. (1) The file's attributes must be 0. Read-only shared memory, or
  1143. shared memory with other attributes, is not yet implemented,
  1144. but may be in the future.
  1145.  
  1146. (2) Two shared memory files cannot have the same name. An attempt
  1147. to create a new shared memory file with the same name as an
  1148. existing one will fail with an access denied error (EACCDN).
  1149.  
  1150. (3) Once the block of memory has been attached to the file, it
  1151. may be accessed by any application that opens the file.
  1152.  
  1153. (4) A shared memory file (and associated block) remain allocated
  1154. even after the program which created it terminates. It can be
  1155. deleted (and the associated memory freed) with an Fdelete()
  1156. system call.
  1157.  
  1158. (5) The size of the shared memory file will be the actual size
  1159. of the memory block. This may be somewhat larger than the
  1160. size requested in the Malloc or Mxalloc request, due to memory
  1161. rounding.
  1162.  
  1163.  
  1164. To use a shared memory block, a client application must open
  1165. the file and use the SHMGETBLK Fcntl to gain access to it.
  1166. For example:
  1167.  
  1168. fd = Fopen("U:\\SHM\\MY.SHARE", 2);
  1169. blk = Fcntl(fd, 0L, SHMGETBLK);
  1170. Fclose(fd); /* optional -- see below */
  1171.  
  1172. Things to note:
  1173.  
  1174. (1) The address of the shared memory block is returned by the
  1175. Fcntl() call. NOTE THAT THIS ADDRESS MAY BE DIFFERENT FOR
  1176. DIFFERENT PROGRAMS. That is, a shared memory block that appears
  1177. at address 0x01000100 in one program may appear at address
  1178. 0x0007f000 in another. In particular, shared memory blocks
  1179. should not contain absolute addresses (e.g. pointers).
  1180.  
  1181. (2) The extra argument passed to Fcntl() is reserved for future
  1182. expansion; use 0L for now to ensure compatibility with
  1183. future versions of MiNT.
  1184.  
  1185. (3) The mode argument in the Fopen() function must be an accurate
  1186. reflection of how the program plans to use the memory; read and
  1187. write access permissions will be enforced in future versions
  1188. of MiNT.
  1189.  
  1190. (4) If no SHMSETBLK has been made for the file, a SHMGETBLK Fcntl
  1191. will return a NULL pointer to indicate an error.
  1192.  
  1193. (5) If a program is finished with a shared memory block and no
  1194. longer wishes to use it, it should call Mfree() with the address
  1195. of the block (i.e. the address returned by Fcntl(fd, 0L, SHMGETBLK)).
  1196.  
  1197. Deleting a Shared Memory File
  1198.  
  1199. The Fdelete() system call may be used to delete a shared memory
  1200. file. This will *not* necessarily free the associated memory;
  1201. the memory will actually be freed only after (1) the file has
  1202. been deleted, and (2) all processes using the memory have
  1203. freed the memory, either directly or as a result of the process
  1204. terminating.
  1205.  
  1206. Fdelete() will fail if the shared memory file is still open.
  1207. Processes may omit the Fclose() call if they wish this to happen;
  1208. it's a way of informing the process trying to delete the file
  1209. that people are still interested in it. Note that it is *not*
  1210. harmful to allow the Fdelete to occur, since (as noted above)
  1211. the memory will not actually be freed until everyone is finished
  1212. with it; but sometimes it may be useful for programs to know that
  1213. the memory is still in use.
  1214.  
  1215.  
  1216. Rendezvous
  1217.  
  1218.  
  1219. The Pmsg() system call provides a simple message based form of IPC. See
  1220. the manual page for Pmsg for further details.
  1221.  
  1222.  
  1223. Semaphores
  1224.  
  1225.  
  1226. Semaphores may be created and otherwise accessed via the Psemaphore system
  1227. call. They are a way to control exclusive access to a resource, with true
  1228. blocking if desired. See Psemaphore's manual page for more details.
  1229.  
  1230.  
  1231.  
  1232. MiNT Friendly Programs
  1233.  
  1234.  
  1235. If you want your program to work well in a multitasking environment,
  1236. you should obey the following rules:
  1237.  
  1238. (1) Don't hog memory. Mshrink() your initial TPA as soon as possible after
  1239. starting, and only Malloc() as much memory as you need.
  1240.  
  1241. (2) Avoid global changes to the system (e.g. modifying the BIOS keyboard
  1242. maps with Keytbl()); if more than one program tries to modify the
  1243. same resource in incompatible ways, confusion is sure to result.
  1244.  
  1245. (3) Use supervisor mode sparingly. In the current implementation, processes
  1246. running in supervisor mode are not preempted, and hence will hog the CPU.
  1247. (You should not rely on this side-effect of supervisor mode; it may go
  1248. away.)
  1249.  
  1250. (4) Don't write directly to screen memory; use the documented AES, VDI,
  1251. and BIOS calls for output.
  1252.  
  1253. (5) Don't access memory that you don't own, and don't make other programs
  1254. access memory that they aren't allowed to. The latter point means that
  1255. if you install an interrupt handler, or provide a cookie that points to
  1256. data or code in your program, you must make sure that the data or code
  1257. pointed to is in global memory (see Appendix A, Memory Protection, for
  1258. details). Otherwise, when another process tries to access the data or
  1259. code (for example, if an interrupt whose vector you replaced occurs)
  1260. it will receive a bus error.
  1261.  
  1262. (6) If you do things in the system like exchanging mouse movement/button
  1263. vectors, then do catch signal 15 (SIGTERM) and other signals that can kill
  1264. your process, and perform cleanup operations in a signal handling routine
  1265. before terminating; this makes it easy for the user to remove your process.
  1266. Otherwise your process can be killed and the vectors you've installed will
  1267. be pointing at empty space.
  1268.  
  1269.  
  1270. MiNT extensions to GEMDOS calls
  1271.  
  1272.  
  1273. Fsfirst()/Fsnext()
  1274. MiNT domain processes (see the Pdomain()) man page) get lower case
  1275. filenames from Fsfirst() or Fsnext() on a TOS filesystem. This is because most
  1276. programs end up converting them to lowercase anyway, to be more Unix-like.
  1277. Please don't do this translation yourself. Let MiNT handle it, because
  1278. some filesystems (e.g. the minix one) are case sensitive! If you really,
  1279. truly, prefer uppercase filenames, run in the TOS domain.
  1280.  
  1281. Fopen()/Fread()/Fwrite()/Flock()
  1282. MiNT implements the Atari file locking protocol, as described in the
  1283. document "GEMDOS File and Record Locking Specification". If no _FLK
  1284. cookie is installed when MINT.PRG is run, one will be created.
  1285.  
  1286. Pexec(100, name, cmdline, environment)
  1287. Similar to Pexec(0, ...), except the calling program does not wait for
  1288. the child to finish. Returns a negative error code, or the (positive)
  1289. process ID of the child.
  1290.  
  1291. Pexec(104, name, basepage, 0L)
  1292. Similar to Pexec(4, ...); starts executing a basepage previously
  1293. set up by Pexec() mode 3, 5, or 7. The caller does not wait for
  1294. the child to finish. Returns a negative error code, or the process ID
  1295. of the child. Note that the child's environment and basepage are
  1296. owned by both the child and the parent (indeed, the child shares all
  1297. memory owned by the parent). \name\ is a pointer to a string
  1298. to be used to supply a name for the new process; if it is NULL, then
  1299. the parent's name is used.
  1300.  
  1301. Pexec(106, name, basepage, 0L)
  1302. Similar to Pexec(104,...) except that the child's environment and
  1303. basepage are \not\ owned by the parent; nor does the child share
  1304. any memory allocated to the parent. Thus, when the child terminates,
  1305. its memory will be freed. A program loaded with mode 3 and then
  1306. started with mode 106 behaves just like one loaded and started with
  1307. mode 100. In the same way, mode 3 followed by mode 6 is just like mode 0.
  1308.  
  1309. Pexec(200, name, cmdline, environment)
  1310. As with Pexec(0,...) and Pexec(100,...) this runs a program. However, with
  1311. this variant the caller is completely replaced with the executing program.
  1312. The process retains its process ID and most other attributes, but all of
  1313. its memory is freed and a new address space is set up for it containing the
  1314. code from the indicated program. Whereas Pexec(0,...) is like a subroutine
  1315. call, Pexec(200,...) is like a "goto." It returns only if an error occurs
  1316. in launching the indicated program (e.g. if not enough memory is available,
  1317. or the file is not found).
  1318.  
  1319.  
  1320. New MiNT calls
  1321.  
  1322.  
  1323. This list shows the name, return type, and argument types of the new
  1324. MiNT system calls, and the corresponding function number for Trap #1.
  1325.  
  1326. word Syield()                                       [ 0x0ff ]
  1327. word Fpipe( word *ptr )                             [ 0x100 ]
  1328. word Fcntl( word f, long arg, word cmd)             [ 0x104 ]
  1329. long Finstat( word f )                              [ 0x105 ]
  1330. long Foutstat( word f )                             [ 0x106 ]
  1331. long Fgetchar(word f, word mode)                    [ 0x107 ]
  1332. long Fputchar( word f, long c, word mode )          [ 0x108 ]
  1333. long Pwait()                                        [ 0x109 ]
  1334. word Pnice( word delta )                            [ 0x10a ]
  1335. word Pgetpid()                                      [ 0x10b ]
  1336. word Pgetppid()                                     [ 0x10c ]
  1337. word Pgetpgrp()                                     [ 0x10d ]
  1338. word Psetpgrp(pid, newgrp)                          [ 0x10e ]
  1339. word Pgetuid()                                      [ 0x10f ]
  1340. word Psetuid( word id )                             [ 0x110 ]
  1341. word Pkill( word pid, word sig )                    [ 0x111 ]
  1342. long Psignal(word sig, long handler)                [ 0x112 ]
  1343. word Pvfork()                                       [ 0x113 ]
  1344. word Pgetgid()                                      [ 0x114 ]
  1345. word Psetgid(word id)                               [ 0x115 ]
  1346. long Psigblock(long mask)                           [ 0x116 ]
  1347. long Psigsetmask(long mask)                         [ 0x117 ]
  1348. long Pusrval(long arg)                              [ 0x118 ]
  1349. word Pdomain(word newdom)                           [ 0x119 ]
  1350. void Psigreturn()                                   [ 0x11a ]
  1351. long Pfork()                                        [ 0x11b ]
  1352. long Pwait3(word flag, long *rusage)                [ 0x11c ]
  1353. word Fselect( word timeout, long *rfds, long *wfds, long *xfds )
  1354.                                                     [ 0x11d ]
  1355. void Prusage( long r[8] )                           [ 0x11e ]
  1356. long Psetlimit(word lim, long value )               [ 0x11f ]
  1357. long Talarm( long secs )                            [ 0x120 ]
  1358. void Pause()                                        [ 0x121 ]
  1359. long Sysconf( word n )                              [ 0x122 ]
  1360. long Psigpending()                                  [ 0x123 ]
  1361. long Dpathconf( char *name, word n )                [ 0x124 ]
  1362. long Pmsg( word mode, long mbox, void *msg )        [ 0x125 ]
  1363. long Fmidipipe( word pid, word in, word out )       [ 0x126 ]
  1364. word Prenice( word pid, word delta )                [ 0x127 ]
  1365. long Dopendir( char *name, word flag )              [ 0x128 ]
  1366. long Dreaddir( word buflen, long dir, char *buf )   [ 0x129 ]
  1367. long Drewinddir( long dir )                         [ 0x12a ]
  1368. long Dclosedir( long dir )                          [ 0x12b ]
  1369. long Fxattr( word flag, char *name, void *buf )     [ 0x12c ]
  1370. long Flink( char *oldname, char *newname )          [ 0x12d ]
  1371. long Fsymlink( char *oldname, char *newname )       [ 0x12e ]
  1372. long Freadlink( word siz, char *buf, char *name )   [ 0x12f ]
  1373. long Dcntl( word cmd, char *name, long arg )        [ 0x130 ]
  1374. long Fchown( char *name, word uid, word gid )       [ 0x131 ]
  1375. long Fchmod( char *name, word mode )                [ 0x132 ]
  1376. long Pumask( unsigned word mode )                   [ 0x133 ]
  1377. long Psemaphore( word mode, long id, long timeout ) [ 0x134 ]
  1378. word Dlock( word mode, word drive )            [ 0x135 ]
  1379. void Psigpause( long sigmask )                [ 0x136 ]
  1380. long Psigaction( word sig, long act, long oact )    [ 0x137 ]
  1381. long Pgeteuid()                        [ 0x138 ]
  1382. long Pgetegid()                        [ 0x139 ]
  1383. long Pwaitpid( word pid, word flag, long *rusage )  [ 0x13a ]
  1384. long Dgetcwd( char *path, word drive, word size )   [ 0x13b ]
  1385. long Salert( char *msg )                [ 0x13c ]
  1386.  
  1387.